/*----------------------------------------------------------------------
  - File name      : STC8Ax_UART.c
  - Author         : Quark Team
  - Update date    : 2020-08-30                   
  -	Copyright      : Gevico Electronic studio   
  - Module comments: UART module.
-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                               INCLUDES                                |
-----------------------------------------------------------------------*/
#include "STC8Ax_UART.h"
/*-----------------------------------------------------------------------
|                                 DATA                                  |
-----------------------------------------------------------------------*/

uint8 UART_BUSY_FLAG[4] = {0,0,0,0};		 //Busy flag of receive 

/*--------------------------------------------------------
| @Description: UART mode configure define function      |
--------------------------------------------------------*/

#define  UART1_MODE_CFG(Mode)  SM0 = Mode >> 1, SM1 = Mode
#define  UART2_MODE_CFG(Mode)  S2CON = (S2CON & 0x3F)|((Mode & 0x02) << 6)
#define  UART3_MODE_CFG(Mode)  S3CON = (S3CON & 0x3F)|((Mode & 0x02) << 6)
#define  UART4_MODE_CFG(Mode)  S4CON = (S4CON & 0x3F)|((Mode & 0x02) << 6)

/*--------------------------------------------------------
| @Description: UART Baud rate configure define function |
--------------------------------------------------------*/

#define UART1_TIMER1_BRTMODE_CFG(BRTMode,BaudRate) { \
AUXR = (AUXR & 0xBF) | (BRTMode << 6); \
T1L = (65536 - SYSCLK_FRE / (BaudRate * 4 * (11 * (!(AUXR & 0x40)) + 1 ))) ; \
T1H = (65536 - SYSCLK_FRE / (BaudRate * 4 * (11 * (!(AUXR & 0x40)) + 1 ))) >> 8;}

#define UARTx_TIMER2_BRTMODE_CFG(BRTMode,BaudRate) { \
AUXR = (AUXR & 0xFB) | (BRTMode << 2); \
T2L = (65536 - SYSCLK_FRE / (BaudRate * 4 * (11 * (!(AUXR & 0x04)) + 1 ))) ; \
T2H = (65536 - SYSCLK_FRE / (BaudRate * 4 * (11 * (!(AUXR & 0x04)) + 1 ))) >> 8;}

#define UART3_TIMER3_BRTMODE_CFG(BRTMode,BaudRate) { \
T4T3M = (T4T3M & 0xFD) | (BRTMode << 1); \
T3L = (65536 - SYSCLK_FRE / (BaudRate * 4 * (11 * (!(T4T3M & 0x02)) + 1 ))) ; \
T3H = (65536 - SYSCLK_FRE / (BaudRate * 4 * (11 * (!(T4T3M & 0x02)) + 1 ))) >> 8;}

#define UART4_TIMER4_BRTMODE_CFG(BRTMode,BaudRate) { \
T4T3M = (T4T3M & 0xDF) | (BRTMode << 5); \
T4L = (65536 - SYSCLK_FRE / (BaudRate * 4 * (11 * (!(T4T3M & 0x20)) + 1 ))) ; \
T4H = (65536 - SYSCLK_FRE / (BaudRate * 4 * (11 * (!(T4T3M & 0x20)) + 1 ))) >> 8;}


/*-----------------------------------------------------------------------
|                               FUNCTION                                |
-----------------------------------------------------------------------*/
/*--------------------------------------------------------
| @Description: UART1 init function                      |
| @param      : const UART_InitType *UARTx               |
| @return     : FSCSTATE : Success / Fail                |
--------------------------------------------------------*/

FSCSTATE UART1_Init(const UART_InitType *UARTx)
{
  UART1_MODE_CFG(UARTx -> Mode);
  switch(UARTx -> BRTGen)
  {
    case UART_BRT_TIM1:
    {
      TR1 = 0;        //Turn off timer0
      ET1 = 0;        //Ban timer0 interrupt
      AUXR &= 0xFE;   //Select timer 1 as baud rate generator
      TMOD &= 0x0F; 	//Timer 1 is fixed to 16 bit auto reload mode
      UART1_TIMER1_BRTMODE_CFG(UARTx -> BRTMode,
                             UARTx -> BaudRate);
      TR1 = 1;        //Turn on timer0
      break;
    }
    case UART_BRT_TIM2:
    {
      AUXR &= 0xEF;  //Turn off timer2
      IE2 &= 0xFB;   //Ban timer2 interrupt
      AUXR |= 0x01;  //Select timer2 as baud rate generator
      UARTx_TIMER2_BRTMODE_CFG(UARTx -> BRTMode,
                             UARTx -> BaudRate);   
      AUXR |= 0X10;  //Turn on timer2
      break;
    }
    default: return FSC_FAIL;
  }
	
  AUXR = (AUXR & 0xDF) | (UARTx -> BRTDouble << 5);
  SCON = (SCON & 0xDF) | (UARTx -> MulitComm << 5);
  SCON = (SCON & 0xEF) | (UARTx -> RxEnable << 4);
  AUXR2 = (AUXR2 & 0xEF) | (UARTx -> Relay << 4);
  UART1_CLEAR_BUSY_FLAG();
	
  return FSC_SUCCESS;
}

/*--------------------------------------------------------
| @Description: UART2 init function                      |
| @param      : const UART_InitType *UARTx               |
| @return     : FSCSTATE : Success / Fail                |
--------------------------------------------------------*/

FSCSTATE UART2_Init(const UART_InitType *UARTx)
{
  UART2_MODE_CFG(UARTx -> Mode);
  if(UARTx -> BRTGen == UART_BRT_TIM2)
  {
    AUXR &= 0xEF;  //Turn off timer2
    IE2 &= 0xFB;   //Ban timer2 interrupt
    UARTx_TIMER2_BRTMODE_CFG(UARTx -> BRTMode,
                           UARTx -> BaudRate);     
    AUXR |= 0X10;  //Turn on timer2
  }
  else return FSC_FAIL;
  S2CON = (S2CON & 0xDF) | (UARTx -> MulitComm << 5);
  S2CON = (S2CON & 0xEF) | (UARTx -> RxEnable << 4);
  UART2_CLEAR_BUSY_FLAG();
  return FSC_SUCCESS;
}

/*--------------------------------------------------------
| @Description: UART3 init function                      |
| @param      : const UART_InitType *UARTx               |
| @return     : FSCSTATE : Success / Fail                |
--------------------------------------------------------*/

FSCSTATE UART3_Init(const UART_InitType *UARTx)
{
  UART3_MODE_CFG(UARTx -> Mode);
  switch(UARTx -> BRTGen)
  {
    case UART_BRT_TIM2:
    {
      AUXR &= 0xEF;  //Turn off timer2
      IE2 &= 0xFB;   //Ban timer2 interrupt
      S3CON &= 0xBF;  //Select timer2 as baud rate generator
      UARTx_TIMER2_BRTMODE_CFG(UARTx -> BRTMode,
                             UARTx -> BaudRate);     
      AUXR |= 0X10;  //Turn on timer2
      break;
    }
    case UART_BRT_TIM3:
    {
      T4T3M &= 0xF7;  //Turn off timer3
      IE2 &= 0xDF;  //Ban timer3 interrupt
      S3CON |= 0x40;    //Select timer3 as baud rate generator
      UART3_TIMER3_BRTMODE_CFG(UARTx -> BRTMode,
                             UARTx -> BaudRate);
      T4T3M |= 0x08; //Turn on timer3 
      break;
    }
    default: return FSC_FAIL;
  }
  S3CON = (S3CON & 0xDF) | (UARTx -> MulitComm << 5);
  S3CON = (S3CON & 0xEF) | (UARTx -> RxEnable << 4);
  UART3_CLEAR_BUSY_FLAG();
  return FSC_SUCCESS;
}

/*--------------------------------------------------------
| @Description: UART4 init function                      |
| @param      : const UART_InitType *UARTx               |
| @return     : FSCSTATE : Success / Fail                |
--------------------------------------------------------*/

FSCSTATE UART4_Init(const UART_InitType *UARTx)
{
  UART4_MODE_CFG(UARTx -> Mode);
  switch(UARTx -> BRTGen)
  {
    case UART_BRT_TIM2:
    {
      AUXR &= 0xEF;  //Turn off timer2
      IE2 &= 0xFB;   //Ban timer2 interrupt
      S4CON &= 0xBF;  //Select timer2 as baud rate generator
      UARTx_TIMER2_BRTMODE_CFG(UARTx -> BRTMode,
                             UARTx -> BaudRate);     
      AUXR |= 0X10;  //Turn on timer2
      break;
    }
    case UART_BRT_TIM4:
    {
      T4T3M &= 0x7F;  //Turn off timer3
      IE2 &= 0xBF;  //Ban timer4 interrupt
      S4CON |= 0x40;   //Select timer3 as baud rate generator
      UART4_TIMER4_BRTMODE_CFG(UARTx -> BRTMode,
                             UARTx -> BaudRate);
      T4T3M |= 0x80; //Turn on timer4
      break;
    }
    default: return FSC_FAIL;
  }
  S4CON = (S4CON & 0xDF) | (UARTx -> MulitComm << 5);
  S4CON = (S4CON & 0xEF) | (UARTx -> RxEnable << 4);
  UART4_CLEAR_BUSY_FLAG();
  return FSC_SUCCESS;
}

/*--------------------------------------------------------
| @Description: UART1 Send byte function                 |
| @param      : uint8 Dat                                |
| @return     : None                                     |
--------------------------------------------------------*/

void UART1_Send_Byte(uint8 Dat)
{
    while(UART1_GET_BUSY_FLAG());
    UART1_SET_BUSY_FLAG();
    SBUF = Dat;
}

/*--------------------------------------------------------
| @Description: UART2 Send byte function                 |
| @param      : uint8 Dat                                |
| @return     : None                                     |
--------------------------------------------------------*/

void UART2_Send_Byte(uint8 Dat)
{
    while(UART2_GET_BUSY_FLAG());
    UART2_SET_BUSY_FLAG();
    S2BUF = Dat;
}

/*--------------------------------------------------------
| @Description: UART3 Send byte function                 |
| @param      : uint8 Dat                                |
| @return     : None                                     |
--------------------------------------------------------*/

void UART3_Send_Byte(uint8 Dat)
{
    while(UART3_GET_BUSY_FLAG());
    UART3_SET_BUSY_FLAG();
    S3BUF = Dat;
}

/*--------------------------------------------------------
| @Description: UART4 Send byte function                 |
| @param      : uint8 Dat                                |
| @return     : None                                     |
--------------------------------------------------------*/

void UART4_Send_Byte(uint8 Dat)
{
    while(UART4_GET_BUSY_FLAG());
    UART4_SET_BUSY_FLAG();
    S4BUF = Dat;
}

/*--------------------------------------------------------
| @Description: UART1 get byte function                  |
| @param      : uint8 *Dat                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART1_Rev_Byte(uint8 *Dat)
{
  while(UART1_GET_BUSY_FLAG());
  *Dat = SBUF;
}

/*--------------------------------------------------------
| @Description: UART2 get byte function                  |
| @param      : uint8 *Dat                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART2_Rev_Byte(uint8 *Dat)
{
  while(UART2_GET_BUSY_FLAG());
  *Dat = S2BUF;
}

/*--------------------------------------------------------
| @Description: UART3 get byte function                  |
| @param      : uint8 *Dat                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART3_Rev_Byte(uint8 *Dat)
{
  while(UART3_GET_BUSY_FLAG());
  *Dat = S3BUF;
}

/*--------------------------------------------------------
| @Description: UART4 get byte function                  |
| @param      : uint8 *Dat                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART4_Rev_Byte(uint8 *Dat)
{
  while(UART4_GET_BUSY_FLAG());
  *Dat = S4BUF;
}

/*--------------------------------------------------------
| @Description: UART1 Send String function               |
| @param      : uint8 *Str                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART1_Send_String(uint8 *Str)
{
	while(*Str)
	{
		UART1_Send_Byte(*(Str++));
	}
}

/*--------------------------------------------------------
| @Description: UART2 Send String function               |
| @param      : uint8 *Str                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART2_Send_String(uint8 *Str)
{
	while(*Str)
	{
		UART2_Send_Byte(*(Str++));
	}
}

/*--------------------------------------------------------
| @Description: UART3 Send String function               |
| @param      : uint8 *Str                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART3_Send_String(uint8 *Str)
{
	while(*Str)
	{
		UART3_Send_Byte(*(Str++));
	}
}

/*--------------------------------------------------------
| @Description: UART4 Send String function               |
| @param      : uint8 *Str                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART4_Send_String(uint8 *Str)
{
	while(*Str)
	{
		UART4_Send_Byte(*(Str++));
	}
}

/*--------------------------------------------------------
| @Description: UART1 Send Array function                |
| @param      : const uint8 *Str                         |
|               uint16 Len                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART1_Send_Array(const uint8 *Str,uint16 Len)
{
	while(Len--)
	{
		UART1_Send_Byte(*(Str++));
	}
}

/*--------------------------------------------------------
| @Description: UART2 Send Array function                |
| @param      : const uint8 *Str                         |
|               uint16 Len                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART2_Send_Array(const uint8 *Str,uint16 Len)
{
	while(Len--)
	{
		UART2_Send_Byte(*(Str++));
	}
}

/*--------------------------------------------------------
| @Description: UART3 Send Array function                |
| @param      : const uint8 *Str                         |
|               uint16 Len                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART3_Send_Array(const uint8 *Str,uint16 Len)
{
	while(Len--)
	{
		UART3_Send_Byte(*(Str++));
	} 
}

/*--------------------------------------------------------
| @Description: UART4 Send Array function                |
| @param      : const uint8 *Str                         |
|               uint16 Len                               |
| @return     : None                                     |
--------------------------------------------------------*/

void UART4_Send_Array(const uint8 *Str,uint16 Len)
{
	while(Len--)
	{
		UART4_Send_Byte(*(Str++));
	}
}

/*-----------------------------------------------------------------------
|          END OF FLIE        (C) COPYRIGHT Gevico Electronics          | 
-----------------------------------------------------------------------*/



